﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using System.Windows;
using System.Windows.Data;
using System.ComponentModel.Composition;

using ETRobocon.RaceTraking.GamePresentation;

using System.IO;
using System.Xml;
using System.Xml.Linq;

using ETRoboConTrakingSystem;

namespace ETRobocon.RaceTraking.GameManagement
{
    //  [PartCreationPolicy(CreationPolicy.NonShared)]
    [Export(typeof(IBonusCheckPointsBuilder))]
    public class BonusCheckPointsBuilder : IBonusCheckPointsBuilder
    {
        private Canvas _canvas;
        //    private RunnerMgmtUserControl _runnerConsole;
        //   private UserControlRunnerStatus _inCourseRunnerState;
        // private UserControlRunnerStatus _outCourseRunnerState;

        public WSRunner TargetRunner { get; set; }

        private WSRunner.CourseName _courseName;
        private Dictionary<string, Point> checkPoints;

        public BonusCheckPointsBuilder()
        {

        }

        public Canvas TargetCanvas
        {
            get { return _canvas; }
            set { _canvas = value; }
        }

        public IRunnerStatus TargetRunnerStatus { get; set; }
        //        public IRunnerStatus inCourseRunnerStatus { get; set; }
        //      public IRunnerStatus outCourseRunnerStatus { get; set; }

        public void SetupBonusSpecChecks(WSRunner.CourseName course, WSBonusSpecList bsList)
        {
            _courseName = course;
            UpdateRunnerBonusResult(bsList);

            BuildCheckPointClearMarkMap(bsList);
            checkPoints = BuildBonusSpecCheckPoints();

            SetupBonusSpecChecksForCource(bsList, checkPoints);
        }

        private void UpdateRunnerBonusResult(WSBonusSpecList bsList)
        {
            if (TargetRunner.BonusResults.Count == 0)
            {
                foreach (WSBonusSpec bs in bsList)
                {
                    WSBonusResult br = new WSBonusResult(bs);
                    TargetRunner.BonusResults.Add(br);
                }
            }
        }

        class CheckPointClearMarkMapSpec
        {
            public int PosX { get; set; }
            public int PosY { get; set; }
            public string ClearMarkKey { get; set; }
            public int Level { get; set; }
        }
        private Dictionary<string, string> bonusSpecNameKeyMap = new Dictionary<string, string>();
        private Dictionary<string, CheckPointClearMarkMapSpec> checkPointToClearMarkMap = new Dictionary<string, CheckPointClearMarkMapSpec>();
        private void BuildCheckPointClearMarkMap(WSBonusSpecList bsList)
        {
            foreach (var bs in bsList)
            {
                checkPointToClearMarkMap.Add(
                    bs.ShortCut,
                    new CheckPointClearMarkMapSpec
                    {
                        PosX = 0,
                        PosY = 0,
                        ClearMarkKey = bs.Name,
                        Level = 1
                    });
                bonusSpecNameKeyMap.Add(bs.Name, bs.ShortCut);
            }

#if false
            System.Reflection.Assembly current = System.Reflection.Assembly.GetExecutingAssembly();
            string source = this.GetType().Namespace + ".GameSpecUIConfig.xml";
            XmlReader uiSpecReader = XmlReader.Create(current.GetManifestResourceStream(source));
            XDocument xRoot = XDocument.Load(uiSpecReader);

            var uiSpecs = xRoot.Elements("UISpecs");
            XElement uiSpec = uiSpecs.Elements("UISpec").First();
            foreach (var courseSpec in uiSpec.Elements("Course"))
            {
                var courseName = courseSpec.Attribute("Name");
                if (courseName.Value.CompareTo(_courseName.ToString()) == 0)
                {
                    foreach (var checkPoint in courseSpec.Elements("CheckPoints").Elements("CheckPoint"))
                    {
                        int posX = System.Convert.ToInt32(checkPoint.Attribute("PosX").Value);
                        int posY = System.Convert.ToInt32(checkPoint.Attribute("PosY").Value);
                        int level = System.Convert.ToInt32(checkPoint.Attribute("ClearMarkLevel").Value);
                        checkPointToClearMarkMap.Add(
                            checkPoint.Attribute("Key").Value,
                            new CheckPointClearMarkMapSpec
                            {
                                PosX = posX,
                                PosY = posY,
                                ClearMarkKey = checkPoint.Attribute("ClearMarkKey").Value,
                                Level = level
                            });
                    }
                    break;
                }
            }
#endif
        }

        private List<ClearMarkSpec> clearMarkSpecs = new List<ClearMarkSpec>();

        public void BuildupClearMarks(WSBonusSpecList bsList)
        {
            foreach (var bs in bsList)
            {
                clearMarkSpecs.Add(
                    new ClearMarkSpec
                    {
                        Name = bs.Name,
                        Key = bs.ShortCut,
                        CanvasLeft = 0,
                        CanvasTop = 0
                    });
            }

#if false
            System.Reflection.Assembly current = System.Reflection.Assembly.GetExecutingAssembly();
            string source = this.GetType().Namespace + ".GameSpecUIConfig.xml";
            XmlReader uiSpecReader = XmlReader.Create(current.GetManifestResourceStream(source));
            XDocument xRoot = XDocument.Load(uiSpecReader);

            var uiSpecs = xRoot.Elements("UISpecs");
            XElement uiSpec = uiSpecs.Elements("UISpec").First();
            foreach (var courseSpec in uiSpec.Elements("Course"))
            {
                var courseName = courseSpec.Attribute("Name");
                if (courseName.Value.CompareTo(_courseName.ToString()) == 0)
                {
                    foreach (var cm in courseSpec.Elements("ClearMarks").Elements("ClearMark"))
                    {
                        int canvasTop = System.Convert.ToInt32(cm.Attribute("CanvasTop").Value);
                        int canvasLeft = System.Convert.ToInt32(cm.Attribute("CanvasLeft").Value);
                        clearMarkSpecs.Add(
                            new ClearMarkSpec
                            {
                                Key = cm.Attribute("Key").Value,
                                CanvasTop = canvasTop,
                                CanvasLeft = canvasLeft
                            });
                    }
                    break;
                }
            }
#endif
            //            if (WSRunner.CourseName.IN.CompareTo(_courseName) == 0)
            //            {
            // this._inCourseRunnerState.BuildClearMarks(clearMarkSpecs);
            //                this.inCourseRunnerStatus.BuildClearMarks(clearMarkSpecs);
            //            }
            //            else
            //            {
            // this._outCourseRunnerState.BuildClearMarks(clearMarkSpecs);
            //                this.outCourseRunnerStatus.BuildClearMarks(clearMarkSpecs);
            //            }
            TargetRunnerStatus.BuildClearMarks(clearMarkSpecs);

        }

        private Dictionary<string, Point> BuildBonusSpecCheckPoints()
        {



            Dictionary<string, Point> checkPoints = new Dictionary<string, Point>();

            if (WSRunner.CourseName.IN.CompareTo(_courseName) == 0)
            {
                //       this._inCourseRunnerState.BuildClearMarks(clearMarkSpecs);

                foreach (var key in checkPointToClearMarkMap.Keys)
                {
                    checkPoints.Add(key, new Point(checkPointToClearMarkMap[key].PosX, checkPointToClearMarkMap[key].PosY));
                }
            }
            else
            {
                //     this._outCourseRunnerState.BuildClearMarks(clearMarkSpecs);

                foreach (var key in checkPointToClearMarkMap.Keys)
                {
                    checkPoints.Add(key, new Point(checkPointToClearMarkMap[key].PosX, checkPointToClearMarkMap[key].PosY));
                }
            }
            return checkPoints;

        }

        private void cb_OnCheckHandleChange(object sender, RoutedEventArgs args)
        {
            CheckBox cb = sender as CheckBox;
            string cbName = cb.Content.ToString();
            bool cbState = false;
            if (cb.IsChecked != null)
            {
                if ((bool)cb.IsChecked)
                {
                    cbState = true;
                }
            }

            //  UserControlRunnerStatus targetStatus = _inCourseRunnerState;
            //            IRunnerStatus targetStatus = inCourseRunnerStatus;
            //          if (_courseName == WSRunner.CourseName.OUT)
            //        {
            //          targetStatus = outCourseRunnerStatus;
            //    }
            string cbKey = bonusSpecNameKeyMap[cbName];
//            CheckPointClearMarkMapSpec mapSpec = checkPointToClearMarkMap[cbName];
            var mapSpec = checkPointToClearMarkMap[cbKey];
            if (mapSpec != null)
            {
                //      targetStatus.ShowCleardMark(mapSpec.ClearMarkKey, mapSpec.Level, cbState);
//                TargetRunnerStatus.ShowCleardMark(mapSpec.ClearMarkKey, mapSpec.Level, cbState);
        //        TargetRunnerStatus.ShowCleardMark(cbName, mapSpec.Level, cbState);
                TargetRunnerStatus.ShowCleardMark(cbKey, mapSpec.Level, cbState);
            }

        }

        private List<CheckMarkMgmtControl> cmmControls;
        public List<CheckMarkMgmtControl> CheckMarkMgmtControls { set { cmmControls = value; } }

        private void SetupBonusSpecChecksForCource(WSBonusSpecList bsList, Dictionary<string, Point> checkPoints)
        {
            int index = 0;
            foreach (WSBonusSpec bs in bsList)
            {
                CheckMarkMgmtControl cmmControl = cmmControls[index++];
                cmmControl.IsEnabled = true;
                CheckBox cb = cmmControl.MyCheckBox;
//                cmmControl.DisplayName = bs.ShortCut;
                cmmControl.DisplayName = bs.Name;
                cb.Checked += new RoutedEventHandler(cb_OnCheckHandleChange);
                cb.Unchecked += new RoutedEventHandler(cb_OnCheckHandleChange);
                WSBonusResult br = TargetRunner.GetBonusResult(bs.ShortCut);
                if (br != null)
                {
                    Binding binding = new Binding("Cleared");
                    binding.Source = br;
                    binding.Mode = BindingMode.TwoWay;
                    cb.SetBinding(CheckBox.IsCheckedProperty, binding);
                }

#if false
                Point point;
                    if (checkPoints.TryGetValue(bs.ShortCut, out point))
                    {
                        CheckBox cb = new CheckBox();
                        cb.Content = bs.ShortCut;
                        cb.MouseRightButtonDown += new System.Windows.Input.MouseButtonEventHandler(cb_MouseRightButtonDown);
                        cb.MouseRightButtonUp += new System.Windows.Input.MouseButtonEventHandler(cb_MouseRightButtonUp);
                        cb.MouseMove += new System.Windows.Input.MouseEventHandler(cb_MouseMove);
                        cb.Checked += new RoutedEventHandler(cb_OnCheckHandleChange);
                        cb.Unchecked += new RoutedEventHandler(cb_OnCheckHandleChange);


                        TargetCanvas.Children.Add(cb);
                        Canvas.SetTop(cb, point.Y);
                        Canvas.SetLeft(cb, point.X);
                        WSBonusResult br = TargetRunner.GetBonusResult(bs.ShortCut);
                        if (br != null)
                        {
                            Binding binding = new Binding("Cleared");
                            binding.Source = br;
                            binding.Mode = BindingMode.TwoWay;
                            cb.SetBinding(CheckBox.IsCheckedProperty, binding);
                        }
                    }
#endif
            }
        }

        private bool _isMouseRightBottonDown = false;

        void cb_MouseMove(object sender, System.Windows.Input.MouseEventArgs e)
        {
            if (_isMouseRightBottonDown)
            {
                CheckBox cb = sender as CheckBox;
                Point p = e.GetPosition(cb);
                double dx = p.X;
                double dy = p.Y;

                Canvas.SetTop(cb, dy);
                Canvas.SetLeft(cb, dx);
            }
        }

        void cb_MouseRightButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            _isMouseRightBottonDown = false;
        }

        void cb_MouseRightButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            _isMouseRightBottonDown = true;
        }
    }

    public class ConsoleBonusCheckSpec
    {
        public string Key { get; set; }
        public int PosX { get; set; }
        public int PosY { get; set; }
        public string ClearMarkKey { get; set; }
        public int ClearMarkLevel { get; set; }
    }


}
